package com.example.xiaomiao.Filter;

import com.example.xiaomiao.Util.JwtUtil;
import io.jsonwebtoken.ExpiredJwtException;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebFilter(asyncSupported = true)
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
        String path = request.getRequestURI();
        return !path.startsWith("/api/") || path.startsWith("/api/public/");  // 只拦截非public请求，放行静态资源
    }

    @Override
    public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        String token = JwtUtil.getTokenFromCookie(request);

        if(token == null){
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.getWriter().write("{\"message\": \"cookie expired, please log in again.\"}");
            return;
        }
        try {
            // 检查令牌是否过期
            if (JwtUtil.isTokenExpired(token)) {
                // 如果令牌过期，返回 401 错误，并附带错误消息
                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                response.getWriter().write("{\"message\": \"Token expired, please log in again.\"}");
                return;
            }
            // 检查id和token是否匹配，即是否在别处登录
            if(JwtUtil.checkUserSignalLogin(token)){
                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                response.getWriter().write("{\"code\": 1000, \"message\": \"another person has logged in elsewhere, exit\"}");
                return;
            }
            // 如果令牌将要过期刷新令牌
            if(JwtUtil.isTokenWillExpired(token)) {
                String id = JwtUtil.extractUsername(token);
                String new_token = JwtUtil.generateToken(id);
                JwtUtil.setTokenToCookieAndCache(response,new_token,id);
            }
        } catch (ExpiredJwtException e) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.getWriter().write("{\"message\": \"Token expired, please log in again.\"}");
            return;
        }

        chain.doFilter(request, response);
    }
}

